module Pagination
  module Helpers
    PARAM_KEY_EXCEPT_LIST = [:authenticity_token, :commit, :utf8, :_method, :script_name, :original_script_name].freeze

    class Tag
      def initialize(template, params: {}, param_name: nil, views_prefix: nil, **options)
        @template, @views_prefix, @options = template, views_prefix, options
        @param_name = param_name || Pagination.config.param_name
        @params = template.params #获取项目中的参数
        @params = @params.to_unsafe_h if @params.respond_to?(:to_unsafe_h)
        @params.except!(*PARAM_KEY_EXCEPT_LIST) #过滤参数
        @params.merge!(params)
      end

      def to_s(locals = {})
        #render自定义模板
        @template.render partial: partial_path, locals: @options.merge(locals)
      end

      def page_url_for(page)
        @template.url_for @params.update(@param_name => page)
      end

      def partial_path
        [@views_prefix,
         'pagination',
         self.class.name.demodulize.underscore
        ].compact.join("/")
      end
    end

    module Link
      def page
        raise "#{__FILE__}:#{__LINE__}, page方法没有实现！"
      end

      def url
        page_url_for page
      end
      def to_s(locals = {})
        locals[:url] = url #赋值后模板中就可以使用url取链接
        super locals #调用Tag#to_s
      end
    end

    class Page < Tag
      include Link
      def page
        @options[:page]
      end

      def to_s(locals = {})
        locals[:page] = page
        super locals
      end
    end

    class FirstPage < Tag
      include Link
      def page
        1
      end
    end
    class LastPage < Tag
      include Link
      def page
        @options[:total_pages]
      end
    end
    class PrevPage < Tag
      include Link
      def page
        @options[:current_page_num] - 1
      end
    end
    class NextPage < Tag
      include Link
      def page
        @options[:current_page_num] + 1
      end
    end
    class Gap < Tag
    end
  end
end